package model;

import java.util.*;

import model.semantics.Node;

/**
 * Represents the state of the expression tree.
 * For most of the nodes, the only reason this exists is to pass on to children.
 * However, leaf nodes such as the VariableNode query this class.
 * @author Sterling Dorminey
 */
public abstract class State<T> {
	
	private Map<String, Node<T>> variableAssignments;
	
	public State() {
		variableAssignments = new HashMap<String, Node<T>>();
	}
	
	/**
	 * Get the reference mapped to the variable. Return a default value if it isn't in the table.
	 */
	public Node<T> getAssignment(String variable) {
		Node<T> result = variableAssignments.get(variable);
		if(result == null) {
			return getDefaultValue();
		}
		return result;
	}
	
	/**
	 * Get the default value to return if the variable does not exist in the state.
	 */
	protected abstract Node<T> getDefaultValue();
	
	/**
	 * Set a variable to map to a reference node.
	 */
	public void setAssignment(String variable, Node<T> value) {
		variableAssignments.put(variable, value);
	}
	
    /**
     * Get the mapping of state variables to the string formats of the expression.
     * NOTE that the variable table returned is not kept in sync with the current state.
     */
    public Map<String, String> getVariableTable() {
    	// We make this a tree map so that the keys are in alphabetical order.
    	Map<String, String> variableTable = new TreeMap<String, String>();
    	for(String var : variableAssignments.keySet()) {
    		String expression = variableAssignments.get(var).toString();
    		variableTable.put(var, expression);
    	}
    	
    	return variableTable;
    }
}
